//再修改
#include <algorithm>
#include <climits>
#include <iostream>
#include <vector>

using namespace std;
int n;
vector<pair<int, int>> materials;
int max_sum() {
  // 找出营养值的最小绝对值，用于确定状态的上限
  int max_nutrition = 0;
  for (const auto &material : materials) {
    max_nutrition = max(max_nutrition, abs(material.first));
  }

  // 初始化动态规划数组
  vector<vector<int>> f(n + 1, vector<int>(2 * max_nutrition + 1, INT_MIN));
  f[0][max_nutrition] = 0; // 将口味值偏移量设为最大营养值的绝对值

  for (int i = 1; i <= n; ++i) {
    int x = materials[i - 1].first;
    int y = materials[i - 1].second;
    for (int j = 0; j <= 2 * max_nutrition; ++j) {
      if (j - x >= 0 && j - x <= 2 * max_nutrition) {
        f[i][j] = max(f[i - 1][j], f[i - 1][j - x] + y);
      } else {
        f[i][j] = f[i - 1][j];
      }
    }
  }

  // 找出满足条件的最大和
  int max_sum = INT_MIN;
  for (int j = 0; j <= max_nutrition; ++j) {
    if (f[n][j + max_nutrition] >= 0) {
      max_sum = max(max_sum, j + f[n][j + max_nutrition]);
    }
  }

  return max_sum;
}

int main() {

  cin >> n;

  materials.resize(n + 1);
  for (int i = 1; i <= n; i++) {
    cin >> materials[i].first >> materials[i].second;
  }

  cout << max_sum() << endl;
  return 0;
}